//package org.example.util;
//
//import cn.afterturn.easypoi.excel.ExcelExportUtil;
//import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
//import cn.afterturn.easypoi.word.WordExportUtil;
//import com.example.exceldemo.enuns.FileType;
//import com.example.exceldemo.exception.ServiceException;
//import com.example.exceldemo.utils.FileUtils;
//import com.example.exceldemo.utils.PdfUtil;
//import org.apache.commons.lang3.ObjectUtils;
//import org.apache.poi.ss.usermodel.Workbook;
//import org.apache.poi.xwpf.usermodel.XWPFDocument;
//import org.docx4j.Docx4J;
//import org.docx4j.convert.out.FOSettings;
//import org.docx4j.fonts.IdentityPlusMapper;
//import org.docx4j.fonts.Mapper;
//import org.docx4j.fonts.PhysicalFonts;
//import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.io.ClassPathResource;
//import org.springframework.core.io.ResourceLoader;
//import org.springframework.stereotype.Component;
//import org.springframework.util.Assert;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletResponse;
//import java.io.*;
//import java.net.URLEncoder;
//import java.text.SimpleDateFormat;
//import java.util.Date;
//import java.util.Map;
//
///**
// * @ClassName WordUtil
// * @Description 描述:easypoi导出工具类
// * @Version 2.0
// **/
//@Component
//public class WordUtil {
//    private static final Logger log = LoggerFactory.getLogger(WordUtil.class);
//
//
//    private final static String TEMPORARY_DIRECTORY = "/data/file/park/temPath";
//
//
//    @Autowired
//    private ResourceLoader resourceLoader;
//
//    /**
//     * @param temPath     模版路径
//     * @param params
//     * @param temFileName 存放临时文件的名字：模版名字.docx
//     * @return
//     */
//    public byte[] exportPdfByte(String temPath, Map<String, Object> params, String temFileName) {
//        log.info("开始生成doc文件");
//        //替换自己服务的存储目录
//        try {
//            String tempDirPath = TEMPORARY_DIRECTORY;
//            File tempDir = new File(tempDirPath);
//            ensureDirectoryExists(tempDir);
//            //linux环境不行
//            //String absolutePath = resourceLoader.getResource("classpath:" + temPath).getFile().getAbsolutePath();
//            //获取模板绝对路径，如果是频繁变更模版，使用完建议删临时模版
//            String path = getTemplatePath(tempDir, temPath, temFileName);
//            return exportPdfAbsolutePath(path, params);
//        } catch (Exception e) {
//            throw new ServiceException("导出获取pdf字节异常：" + e.getMessage());
//        }
//    }
//
//    /**
//     * 获取word文件字节数组
//     *
//     * @param templatePath 模版路径
//     * @param tempFileName 存放临时文件的模版名字：例：1.docx
//     * @return
//     * @throws IOException
//     */
//    public byte[] exportWordByte(Map<String, Object> params, String templatePath, String tempFileName) {
//        try {
//            log.info("开始生成doc文件");
//            File tempDir = new File(TEMPORARY_DIRECTORY);
//            ensureDirectoryExists(tempDir);
//            String path = getTemplatePath(tempDir, templatePath, tempFileName);
//
//            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//            log.info("开启读取doc模板,最终模版路径：" + path);
//            //path必须是绝对路径
//            XWPFDocument doc = WordExportUtil.exportWord07(path, params);
//            log.info("读取doc模板结束.....");
//            doc.write(byteArrayOutputStream);
//            byte[] documentBytes = byteArrayOutputStream.toByteArray();
//            return documentBytes;
//        } catch (Exception e) {
//            log.error("生成doc文件失败", e);
//            throw new ServiceException("生成doc文件失败", e);
//        }
//    }
//
//    /**
//     * 导出PDF
//     *
//     * @param templatePath word模板地址
//     * @param params       替换的参数
//     * @return pdf的绝对路径
//     */
//    public byte[] exportPdfAbsolutePath(String templatePath, Map<String, Object> params) {
//        // 生成的wold文档文件名
//        String woldFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".docx";
//        //保存的文件路径名
//        String saveDir = TEMPORARY_DIRECTORY + File.separator + "pdf";
//        // 生成的pdf文件名
//        String pdfFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".pdf";
//        // 导出wold文档 返回值为生成的wold文档全路径
//        String word = exportWord(templatePath, saveDir, woldFileName, params);
//        cn.hutool.core.lang.Assert.notNull(word, "word路径不能为空");
//        // 自定义生成的pdf全路径
//        String pdfPath = saveDir + File.separator + pdfFileName;
//        // 导出pdf,同时删除生成的wold文档
//        convertDocx2Pdf(word, pdfPath);
//        //获取输出字节数组
//        byte[] aByte = FileUtils.getByte(pdfPath);
//        //删除pdf临时目录和文件
//        delFileWord(saveDir, pdfFileName);
//        //删除临时模版,如果频繁更新，建议删
//        //delFile(templatePath);
//        return aByte;
//    }
//
//
//    /**
//     * 导出word
//     * 模版变量中变量格式：{{foo}}
//     *
//     * @param templatePath word模板地址
//     * @param saveDir      word文档保存的路径
//     * @param fileName     文件名
//     * @param params       替换的参数
//     */
//    public String exportWord(String templatePath, String saveDir, String fileName, Map<String, Object> params) {
//        Assert.notNull(templatePath, "模板路径不能为空");
//        Assert.notNull(saveDir, "临时文件路径不能为空");
//        Assert.notNull(fileName, "导出文件名不能为空");
//        Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");
//        if (!saveDir.endsWith("/")) {
//            saveDir = saveDir + File.separator;
//        }
//
//        File dir = new File(saveDir);
//        if (!dir.exists()) {
//            dir.mkdirs();
//        }
//        String savePath = saveDir + fileName;
//
//        try {
//            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
//            FileOutputStream fos = new FileOutputStream(savePath);
//            doc.write(fos);
//            fos.flush();
//            fos.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return savePath;
//    }
//
//    /**
//     * @param templatePath 模版存放静态资源位置
//     * @param fileName
//     * @param params
//     * @param fileType
//     * @param tempFileName 存放临时文件的模版名字：例：1.docx
//     */
//    public void exportWord(String templatePath, String fileName, Map<String, Object> params, FileType fileType, String tempFileName) {
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//        String path = "";
//        OutputStream out = null;
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        try {
//            log.info("开始生成" + fileType.getType() + "文件");
//            //替换自己服务的存储目录
//            String tempDirPath = TEMPORARY_DIRECTORY;
//            File tempDir = new File(tempDirPath);
//            ensureDirectoryExists(tempDir);
//            //获取模板绝对路径，如果是频繁变更模版，使用完建议删临时模版
//            path = getTemplatePath(tempDir, templatePath, tempFileName);
//            log.info("开启读取模板,最终模版路径：" + path);
//            //path必须是绝对路径
//            try (XWPFDocument doc = WordExportUtil.exportWord07(path, params);) {
//                log.info("读取模板结束.....");
//                doc.write(bos);
//                byte[] documentBytes = bos.toByteArray();
//                // 设置响应头
//                response.setContentType(fileType.getDesc());
//                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + fileType.getType());
//                //设置字符编码
//                response.setCharacterEncoding("UTF-8");
//                out = response.getOutputStream();
//                out.write(documentBytes);
//            }
//
//        } catch (Exception e) {
//            log.error("导出" + fileType.getType() + "类型文档失败：" + e.getMessage());
//            throw new ServiceException("导出" + fileType.getType() + "类型文档失败：" + e.getMessage());
//        } finally {
//            //这一步看具体需求，模版要不要删
////            if (StringUtils.isNotBlank(path))
//
////                delFile(path);
//            try {
//                if (out != null) {
//                    out.close();
//                }
//                if (bos != null) {
//                    bos.close();
//                }
//            } catch (Exception ex) {
//                ex.printStackTrace();
//            }
//        }
//    }
//
//    /**
//     * 导出Excel文件
//     *
//     * @param templatePath Excel模板路径
//     * @param fileName     导出文件名
//     * @param params       导出数据，以键值对形式存储
//     * @param fileType     文件类型枚举，用于设置响应头
//     * @param tempFileName 临时文件名，用于频繁变更模板时
//     * @param sheetName    工作表名称数组，用于设置多个工作表
//     */
//    public void exportExcel(String templatePath, String fileName, Map<String, Object> params, FileType fileType, String tempFileName, String[] sheetName) {
//        // 获取HttpServletResponse对象
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//        String path = "";
//        OutputStream out = null;
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        try {
//            // 记录开始生成文件的日志
//            log.info("开始生成" + fileType.getType() + "文件");
//            // 替换自己服务的存储目录
//            String tempDirPath = TEMPORARY_DIRECTORY;
//            File tempDir = new File(tempDirPath);
//            // 确保临时目录存在
//            ensureDirectoryExists(tempDir);
//            // 获取模板绝对路径，如果是频繁变更模版，使用完建议删临时模版
//            path = getTemplatePath(tempDir, templatePath, tempFileName);
//            // 设置为ture，代表支持多sheet模板导出
//            TemplateExportParams exportParams = new TemplateExportParams(path, true);
//            // 设置sheet名称
//            if (sheetName != null && sheetName.length > 0)
//                exportParams.setSheetName(sheetName);
//            // 记录读取模板开始的日志
//            log.info("开启读取模板,最终模版路径：" + path);
//            // path必须是绝对路径
//            try (Workbook doc = ExcelExportUtil.exportExcel(exportParams, params);) {
//                // 记录读取模板结束的日志
//                log.info("读取模板结束.....");
//                // 将Excel数据写入字节数组输出流
//                doc.write(bos);
//                byte[] documentBytes = bos.toByteArray();
//                // 设置响应头
//                response.setContentType(fileType.getDesc());
//                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + fileType.getType());
//                // 设置字符编码
//                response.setCharacterEncoding("UTF-8");
//                // 获取响应输出流
//                out = response.getOutputStream();
//                // 将字节数组写入响应输出流
//                out.write(documentBytes);
//            }
//
//        } catch (Exception e) {
//            // 记录导出失败的错误日志
//            log.error("导出" + fileType.getType() + "类型文档失败：" + e.getMessage());
//            // 抛出服务异常，提示导出失败
//            throw new ServiceException("导出" + fileType.getType() + "类型文档失败：" + e.getMessage());
//        } finally {
//            // 根据需求决定是否删除模板
////            if (StringUtils.isNotBlank(path))
//
////                delFile(path);
//            // 关闭输出流和字节数组输出流
//            try {
//                if (out != null) {
//                    out.close();
//                }
//                if (bos != null) {
//                    bos.close();
//                }
//            } catch (Exception ex) {
//                // 打印关闭流时的异常堆栈信息
//                ex.printStackTrace();
//            }
//        }
//    }
//
//
//    /**
//     * 删除零时生成的文件和目录
//     */
//    public void delFileWord(String filePath, String fileName) {
//        File file = new File(filePath + fileName);
//        File file1 = new File(filePath);
//        if (file.exists()) {
//            file.delete();
//            log.info("删除临时文件成功");
//        }
//        if (file1.exists()) {
//            file1.delete();
//            log.info("删除临时目录成功");
//        }
//    }
//
//    /**
//     * 删除临时文件
//     */
//    public void delFile(String fileName) {
//        File file = new File(fileName);
//        file.delete();
//    }
//
//    /**
//     * @param wordPath word文件路径
//     * @param pdfPath  pdf输出路径
//     */
//    public void convertDocx2Pdf(String wordPath, String pdfPath) {
//        OutputStream os = null;
//        InputStream is = null;
//        if (pdfPath.endsWith("/")) {
//            pdfPath = pdfPath + File.separator;
//        }
//        try {
//            is = new FileInputStream(new File(wordPath));
//            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
//            setFontMapper(mlPackage);
//            os = new FileOutputStream(pdfPath);
//            //docx4j  docx转pdf
//            FOSettings foSettings = Docx4J.createFOSettings();
//            foSettings.setWmlPackage(mlPackage);
//            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            // 删除word文档的地址
//            File file = new File(wordPath);
//            if (file != null && file.isFile() && file.exists())
//                file.delete();
//            try {
//                if (is != null) {
//                    is.close();
//                }
//                if (os != null) {
//                    os.close();
//                }
//            } catch (Exception ex) {
//                ex.printStackTrace();
//            }
//        }
//    }
//
//    /**
//     * 设置字体映射器
//     * 此方法用于解决文档中中文字体的乱码问题
//     * 它通过将文档中的中文字体映射到Java中对应的物理字体来确保字体的正确显示
//     *
//     * @param mlPackage WordprocessingMLPackage对象，用于处理Word文档
//     */
//    private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {
//        // 创建字体映射器实例
//        Mapper fontMapper = new IdentityPlusMapper();
//
//        // 将常见的中文字体与其对应的物理字体进行映射
//        fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
//        fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
//        fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
//        fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
//        fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
//        fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
//        fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
//        fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
//        fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
//        fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
//        fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
//        fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
//        fontMapper.put("等线", PhysicalFonts.get("SimSun"));
//        fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
//        fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
//        fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
//        fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
//        fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
//        fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
//        fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
//        fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
//        fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
//        fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
//        fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
//        //解决宋体（正文）和宋体（标题）的乱码问题
//        PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
//        PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
//
//        // 将字体映射器设置到Word文档处理对象中
//        mlPackage.setFontMapper(fontMapper);
//    }
//
//
//    /**
//     * 将指定路径的图像文件转换为Base64编码的字节数组
//     *
//     * @param path 图像文件的路径
//     * @return 包含图像Base64编码的字节数组
//     */
//    public byte[] getImageBase64(String path) throws IOException {
//        InputStream input = new FileInputStream(path);
//        ByteArrayOutputStream output = new ByteArrayOutputStream();
//        byte[] buf = new byte[1024];
//        int numBytesRead = 0;
//
//        while ((numBytesRead = input.read(buf)) != -1) {
//            // 将读取的数据写入到输出流中
//            output.write(buf, 0, numBytesRead);
//        }
//
//        // 将输出流中的数据转换为字节数组
//        byte[] data = output.toByteArray();
//        output.close();
//        input.close();
//
//        // 返回包含图像Base64编码的字节数组
//        return data;
//    }
//
//
//    /**
//     * 确保给定目录存在，如果不存在则尝试创建它
//     *
//     * @param directory 要确保存在的目录文件对象
//     * @throws IOException 如果目录创建失败，则抛出IOException
//     */
//    private static void ensureDirectoryExists(File directory) throws IOException {
//        // 检查目录是否已经存在
//        if (!directory.exists()) {
//            if (!directory.mkdirs()) {
//                log.error("无法创建临时目录：" + directory.getAbsolutePath());
//                throw new IOException("无法创建临时目录：" + directory.getAbsolutePath());
//            }
//        }
//    }
//
//    /***
//     * 获取模版的绝对路径
//     * @param tempDir
//     * @param templatePath
//     * @param tempFileName 模版名字+文件类型后缀 1.docx
//     * @return
//     * @throws IOException
//     */
//    private static String getTemplatePath(File tempDir, String templatePath, String tempFileName) throws IOException {
//        //判断模版文件是否在临时目录，如果不存在则创建
//        File templateFile = new File(tempDir, tempFileName);
//        if (!templateFile.exists()) {
//            log.info("模板文件不存在于临时目录，将从Classpath中复制。");
//            copyTemplateToFile(templateFile, templatePath);
//        }
//        log.info("使用现有模板文件：" + templateFile.getAbsolutePath());
//        return templateFile.getAbsolutePath();
//    }
//
//    /**
//     * 在临时目录创建模版
//     *
//     * @param outputFile
//     * @param templatePath
//     * @throws IOException
//     */
//    private static void copyTemplateToFile(File outputFile, String templatePath) throws IOException {
//        ClassPathResource resource = new ClassPathResource(templatePath);
//        try (InputStream inputStream = resource.getInputStream();
//             FileOutputStream outputStream = new FileOutputStream(outputFile)) {
//            if (ObjectUtils.isEmpty(inputStream)) {
//                throw new IOException("获取模板inputStream为空......");
//            }
//            byte[] buffer = new byte[1024];
//            int bytesRead;
//            while ((bytesRead = inputStream.read(buffer)) != -1) {
//                outputStream.write(buffer, 0, bytesRead);
//            }
//            log.info("写入临时目录结束:" + outputFile.getParent());
//        }
//    }
//}